package com.zzf.concurrent.example.design.pattern.customer.producer;

import java.util.LinkedList;

/**
 * 消息队列，阻塞试get/set
 * @author GaoFeng2017
 * @date 2019/9/9 15:52
 */
public class MessageQueue<T> {

    private final LinkedList<T> queue;
    private final int limit;
    private final static int DEFAULT_QUEUE_LIMIT = 10;

    public MessageQueue() {
        this(DEFAULT_QUEUE_LIMIT);
    }

    public MessageQueue(int limit) {
        this.queue = new LinkedList<>();
        this.limit = limit;
    }

    /**
     * 获取队首元素，如果队列没有任何元素，则阻塞当前获取操作
     * @author ZengZhengFang
     * @date 2019/9/9 16:18
     * @param
     * @return java.lang.String
     */
    public T poll() {
        synchronized (this.queue) {

            while (queue.peek() == null) {
                try {
                    this.queue.wait();
                } catch (InterruptedException e) {
                    return null;
                }
            }

            queue.notifyAll();
            return this.queue.poll();

        }
    }

    /**
     * 推送消息到队尾，如果超过队列的长度限制，则一直阻塞
     * @author ZengZhengFang
     * @date 2019/9/9 16:24
     * @param message 待推送的消息
     * @return void
     */
    public void push(T message) {
        synchronized (this.queue) {
            while (queue.size() >= limit) {
                try {
                    this.queue.wait();
                } catch (InterruptedException e) {
                    return;
                }
            }
            queue.push(message);
            queue.notifyAll();
        }
    }

    public int getLimit() {
        return limit;
    }
}
